package com.css.fxfzypg.modules.baseData.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.css.fxfzypg.base.attachment.service.AttachmentInfoService;
import com.css.fxfzypg.base.response.RestResponse;
import com.css.fxfzypg.common.utils.CheckObjFields;
import com.css.fxfzypg.common.utils.UpdateUtil;
import com.css.fxfzypg.common.utils.excel.ExcelReaderUtil;
import com.css.fxfzypg.common.utils.excel.ExcelResult;
import com.css.fxfzypg.constants.FxfzConstants;
import com.css.fxfzypg.constants.YNEnum;
import com.css.fxfzypg.modules.baseData.entity.GdpEntity;
import com.css.fxfzypg.modules.baseData.entity.HosPeoEntity;
import com.css.fxfzypg.modules.baseData.repository.CountiesConditionRepository;
import com.css.fxfzypg.modules.baseData.entity.CountiesCondition;
import com.css.fxfzypg.modules.baseData.service.CountiesConditionService;
import com.css.fxfzypg.modules.baseData.queryParams.CountiesConditionQueryParams;
import com.css.fxfzypg.modules.baseData.vo.CountiesConditionVO;
import com.css.fxfzypg.util.*;
import com.css.fxfzypg.zcpt.sys.service.SysAreaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class CountiesConditionServiceImpl implements CountiesConditionService {
    @Resource
    CountiesConditionRepository countiesConditionRepository;

    @Resource
    private SysAreaService sysAreaService;
    @Resource
    AttachmentInfoService attachmentInfoService;
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 修改
     *
     * @param countiesCondition 实体
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse updateCountiesCondition(CountiesCondition countiesCondition) {
        //数据判断是否符合要求
        StringBuilder message = getMessage(countiesCondition);
        if (message.length() > 0) {
            return RestResponse.fail(String.valueOf(message));
        }
        CountiesCondition countiesConditionById = countiesConditionRepository.getCountiesConditionById(countiesCondition.getCcId());
        //把countiesConditionById(通过Id查询)原实体，只赋值到countiesCondition目标实体的空值，
        UpdateUtil.copyNullProperties(countiesConditionById, countiesCondition);
        countiesCondition.setUpdateUser(PlatformSessionUtils.getUserId());
        countiesCondition.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
        int i = countiesConditionRepository.updateCountiesCondition(countiesCondition);
        return ResponseCreator.createSuccessResponse(i, "修改成功！");
    }

    /**
     * 新增elevation
     *
     * @param entity
     * @return
     */
    @Override
    @Transactional
    public RestResponse saveCountiesCondition(CountiesCondition entity) {
        Map<String, String> areaIdCodeMap = (Map<String, String>) JSONObject.parse(redisTemplate.opsForValue().get(FxfzConstants.CACHE_SYS_KEY + "areaIdCodeMap"));
        //查询库是否有该省市县的数据
        CountiesCondition countiesCondition = countiesConditionRepository.getCountiesConditionBydivision(entity.getProvinceId(),
                entity.getCityId(), entity.getPrefectureId());
        if (countiesCondition != null) {
            return RestResponse.fail("该省市县已存在，请去修改！！");
        }
        entity.setCcId(UUIDGenerator.getUUID());
        entity.setCreateUser(PlatformSessionUtils.getUserId());
        entity.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
        entity.setIsDelete(YNEnum.N.toString());
        String divisionNames = null;
        try {
            //根据省市县Id,获取省市县名称;单个id可以获得单个名称;多个id，用逗号分割，可以获得多个名称
            String divisionIds = entity.getProvinceId() + "," + entity.getCityId() + "," + entity.getPrefectureId();
            divisionNames = sysAreaService.getAreaNameByAreaId(divisionIds);
        } catch (Exception e) {
            return RestResponse.fail("省市县的id不符合符合规范！ ");
        }
        String[] split = divisionNames.split(",");
        entity.setProvince(split[0]);
        if (split.length == 2) {
            entity.setCity(split[0]);
            entity.setPrefecture(split[1]);
        } else {
            entity.setCity(split[1]);
            entity.setPrefecture(split[2]);
        }
        StringBuilder erorrMessage = getMessage(entity);
        entity.setIsDelete(YNEnum.N.toString());
        entity.setCreateUser(PlatformSessionUtils.getUserId());
        entity.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
        entity.setProvinceCode(areaIdCodeMap.get(entity.getProvinceId()));
        entity.setCityCode(areaIdCodeMap.get(entity.getCityId()));
        entity.setPrefectureCode(areaIdCodeMap.get(entity.getPrefectureId()));
        if (erorrMessage.length() < 1) {
            int i = countiesConditionRepository.saveCountiesCondition(entity);
            return ResponseCreator.createSuccessResponse(i, "保存成功！");
        }
        return RestResponse.fail(String.valueOf(erorrMessage));
    }

    /**
     * 按条件分页查询
     *
     * @param queryParams 查询的条件
     * @param curPage     第几页
     * @param pageSize    每页的条数
     * @return
     */
    @Override
    public JSONObject getAllCountiesCondition(CountiesConditionQueryParams queryParams, int curPage, int pageSize) {
        return countiesConditionRepository.getAllCountiesConditionParams(queryParams
                , curPage, pageSize);
    }

    /**
     * 根据id查询CountiesCondition数据
     *
     * @param id ccId
     * @return
     */
    @Override
    public CountiesConditionVO getCountiesConditionById(String id) {
        CountiesCondition countiesCondition = countiesConditionRepository.getCountiesConditionById(id);
        CountiesConditionVO countiesConditionVO = new CountiesConditionVO();
        UpdateUtil.copyNullProperties(countiesCondition, countiesConditionVO);
        if (PlatformObjectUtils.isNotEmpty(countiesCondition.getCcLandformAttachment()))
            countiesConditionVO.setCcLandformAttachment(attachmentInfoService.queryFile(countiesCondition.getCcLandformAttachment()));
        if (PlatformObjectUtils.isNotEmpty(countiesCondition.getCcSeismotectonicsAttachment()))
            countiesConditionVO.setCcSeismotectonicsAttachment(attachmentInfoService.queryFile(countiesCondition.getCcSeismotectonicsAttachment()));
        if (PlatformObjectUtils.isNotEmpty(countiesCondition.getCcClimateAttachment()))
            countiesConditionVO.setCcClimateAttachment(attachmentInfoService.queryFile(countiesCondition.getCcClimateAttachment()));
        if (PlatformObjectUtils.isNotEmpty(countiesCondition.getCcNationAttachment()))
            countiesConditionVO.setCcNationAttachment(attachmentInfoService.queryFile(countiesCondition.getCcNationAttachment()));
        if (PlatformObjectUtils.isNotEmpty(countiesCondition.getCcEconomyAttachment()))
            countiesConditionVO.setCcEconomyAttachment(attachmentInfoService.queryFile(countiesCondition.getCcEconomyAttachment()));
        if (PlatformObjectUtils.isNotEmpty(countiesCondition.getCcTrafficAttachment()))
            countiesConditionVO.setCcTrafficAttachment(attachmentInfoService.queryFile(countiesCondition.getCcTrafficAttachment()));
        if (PlatformObjectUtils.isNotEmpty(countiesCondition.getCcDisasterAttachment()))
            countiesConditionVO.setCcDisasterAttachment(attachmentInfoService.queryFile(countiesCondition.getCcDisasterAttachment()));
        if (PlatformObjectUtils.isNotEmpty(countiesCondition.getCcFacilityAttachment()))
            countiesConditionVO.setCcFacilityAttachment(attachmentInfoService.queryFile(countiesCondition.getCcFacilityAttachment()));
        if (PlatformObjectUtils.isNotEmpty(countiesCondition.getCcHistoryAttachment()))
            countiesConditionVO.setCcHistoryAttachment(attachmentInfoService.queryFile(countiesCondition.getCcHistoryAttachment()));
        if (PlatformObjectUtils.isNotEmpty(countiesCondition.getCcTraitAttachment()))
            countiesConditionVO.setCcTraitAttachment(attachmentInfoService.queryFile(countiesCondition.getCcTraitAttachment()));
        if (PlatformObjectUtils.isNotEmpty(countiesCondition.getCcSchoolAttachment()))
            countiesConditionVO.setCcSchoolAttachment(attachmentInfoService.queryFile(countiesCondition.getCcSchoolAttachment()));
        if (PlatformObjectUtils.isNotEmpty(countiesCondition.getCcHospitalAttachment()))
            countiesConditionVO.setCcHospitalAttachment(attachmentInfoService.queryFile(countiesCondition.getCcHospitalAttachment()));
        if (PlatformObjectUtils.isNotEmpty(countiesCondition.getCcHazardAttachment()))
            countiesConditionVO.setCcHazardAttachment(attachmentInfoService.queryFile(countiesCondition.getCcHazardAttachment()));
        if (PlatformObjectUtils.isNotEmpty(countiesCondition.getCcReservoirAttachment()))
            countiesConditionVO.setCcReservoirAttachment(attachmentInfoService.queryFile(countiesCondition.getCcReservoirAttachment()));
        if (PlatformObjectUtils.isNotEmpty(countiesCondition.getCcMessageAttachment()))
            countiesConditionVO.setCcMessageAttachment(attachmentInfoService.queryFile(countiesCondition.getCcMessageAttachment()));
        return countiesConditionVO;
    }

    /**
     * 逻辑删除，修改数据标志位
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteCountiesConditions(String id) {
        String userId = PlatformSessionUtils.getUserId();
        Timestamp timestamp = PlatformDateUtils.getCurrentTimestamp();
        countiesConditionRepository.deleteCountiesConditionsById(id, timestamp, userId);
    }

    /**
     * 导出表内数据
     *
     * @throws IOException
     */
    @Override
    public List<CountiesCondition> getAll() {

        return countiesConditionRepository.getAll();
    }

    /**
     * 对实体类数据进行校验
     *
     * @param entity 实体类
     * @return 错误信息
     */
    private StringBuilder getMessage(CountiesCondition entity) {
        StringBuilder erorrMessage = new StringBuilder();
        if (PlatformObjectUtils.isEmpty(entity.getCcLandform())) {
            erorrMessage.append("地形地貌特征 不能为空！ ");
        } else {
            if (entity.getCcLandform().length() > 500) {
                erorrMessage.append("地形地貌特征 不能超过500字！ ");
            }
        }
        if (PlatformObjectUtils.isEmpty(entity.getCcSeismotectonics())) {
            erorrMessage.append("地震构造特征 不能为空！ ");
        } else {
            if (entity.getCcSeismotectonics().length() > 500) {
                erorrMessage.append("地震构造特征 不能超过500字！ ");
            }
        }
        if (PlatformObjectUtils.isEmpty(entity.getCcClimate())) {
            erorrMessage.append("气候特征 不能为空！ ");
        } else {
            if (entity.getCcClimate().length() > 500) {
                erorrMessage.append("气候特征 不能超过500字！ ");
            }
        }
        if (PlatformObjectUtils.isEmpty(entity.getCcNation())) {
            erorrMessage.append("人口民族特性 不能为空！ ");
        } else {
            if (entity.getCcNation().length() > 500) {
                erorrMessage.append("人口民族特性 不能超过500字！ ");
            }
        }
        if (PlatformObjectUtils.isEmpty(entity.getCcEconomy())) {
            erorrMessage.append("经济产业特性 不能为空！ ");
        } else {
            if (entity.getCcEconomy().length() > 500) {
                erorrMessage.append("经济产业特性 不能超过500字！ ");
            }
        }
        if (PlatformObjectUtils.isEmpty(entity.getCcTraffic())) {
            erorrMessage.append("交通情况 不能为空！ ");
        } else {
            if (entity.getCcTraffic().length() > 500) {
                erorrMessage.append("交通情况 不能超过500字！ ");
            }
        }
        if (PlatformObjectUtils.isEmpty(entity.getCcDisaster())) {
            erorrMessage.append("地质灾害情况 不能为空！ ");
        } else {
            if (entity.getCcDisaster().length() > 500) {
                erorrMessage.append("地质灾害情况 不能超过500字！ ");
            }
        }
        if (PlatformObjectUtils.isEmpty(entity.getCcFacility())) {
            erorrMessage.append("基础设施 不能为空！ ");
        } else {
            if (entity.getCcFacility().length() > 500) {
                erorrMessage.append("基础设施 不能超过500字！ ");
            }
        }
        if (PlatformObjectUtils.isEmpty(entity.getCcHistory())) {
            erorrMessage.append("历史地震情况 不能为空！ ");
        } else {
            if (entity.getCcHistory().length() > 500) {
                erorrMessage.append("历史地震情况 不能超过500字！ ");
            }
        }
        if (PlatformObjectUtils.isEmpty(entity.getCcTrait())) {
            erorrMessage.append("其他区域特点 不能为空！ ");
        } else {
            if (entity.getCcTrait().length() > 500) {
                erorrMessage.append("其他区域特点 不能超过500字！ ");
            }
        }
        if (PlatformObjectUtils.isEmpty(entity.getCcSchool())) {
            erorrMessage.append("主要中小学信息统计 不能为空！ ");
        } else {
            if (entity.getCcSchool().length() > 500) {
                erorrMessage.append("主要中小学信息统计 不能超过500字！ ");
            }
        }
        if (PlatformObjectUtils.isEmpty(entity.getCcHistory())) {
            erorrMessage.append("主要医院信息统计 不能为空！ ");
        } else {
            if (entity.getCcHistory().length() > 500) {
                erorrMessage.append("主要医院信息统计 不能超过500字！ ");
            }
        }
        if (PlatformObjectUtils.isEmpty(entity.getCcHazard())) {
            erorrMessage.append("重大危险源统计 不能为空！ ");
        } else {
            if (entity.getCcHazard().length() > 500) {
                erorrMessage.append("重大危险源统计 不能超过500字！ ");
            }
        }
        if (PlatformObjectUtils.isEmpty(entity.getCcReservoir())) {
            erorrMessage.append("水库信息统计 不能为空！ ");
        } else {
            if (entity.getCcReservoir().length() > 500) {
                erorrMessage.append("水库信息统计 不能超过500字！ ");
            }
        }
        if (PlatformObjectUtils.isEmpty(entity.getCcMessage())) {
            erorrMessage.append("综合信息 不能为空！ ");
        } else {
            if (entity.getCcMessage().length() > 500) {
                erorrMessage.append("综合信息 不能超过500字！ ");
            }
        }
        return erorrMessage;
    }

    /**
     * 导入数据
     *
     * @param file
     * @throws IOException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse importExcel(MultipartFile file) throws IOException {
        Map<String, String> areaIdCodeMap = (Map<String, String>) JSONObject.parse(redisTemplate.opsForValue().get(FxfzConstants.CACHE_SYS_KEY + "areaIdCodeMap"));
        List<CountiesCondition> countiesConditions = FileUtil.importExcel(file, 0, 1, CountiesCondition.class);
        //存储错误的信息
        StringBuilder message = new StringBuilder();
        //存储insert数据
        List<CountiesCondition> saveList = new ArrayList<>();
        //存储update数据
        List<CountiesCondition> updateList = new ArrayList<>();
        int count = 0;
        for (CountiesCondition entity : countiesConditions) {
            if (CheckObjFields.isAllFieldNull(entity)) {
                count++;
                continue;
            }
            message = getMessage(entity);
            if (message.length() > 0) {
                continue;
            }
            String divisionIds = null;
            try {
                //判断省市县的名称是否符合规范
                divisionIds = sysAreaService.getIdByCondition(URLEncoder.encode(entity.getProvince(), "utf-8"),
                        URLEncoder.encode(entity.getCity(), "utf-8"),
                        URLEncoder.encode(entity.getPrefecture(), "utf-8"));
            } catch (Exception e) {
            }
            if (PlatformObjectUtils.isEmpty(divisionIds)) {
                message.append("第" + (countiesConditions.indexOf(entity) + 2) + "行数据，省市县的名称不规范！！<br/>");
                continue;
            }
            CountiesCondition countiesConditionBydivision = countiesConditionRepository.getCountiesConditionBydivision(entity.getProvinceId(), entity.getCityId(), entity.getPrefectureId());
            if (PlatformObjectUtils.isEmpty(countiesConditionBydivision)) {
                //不存在则insert
                saveList.add(entity);
            } else {
                //存在则update
                UpdateUtil.copyNullProperties(countiesConditionBydivision, entity);
                updateList.add(entity);
            }
        }
        if (message.length() != 0) {
            return RestResponse.fail("导入失败:".concat(String.valueOf(message)));
        }
        //存储保存或修改数据库数据的条数
        int saveNum = 0;
        if (PlatformObjectUtils.isNotEmpty(saveList)) {
            for (CountiesCondition entity : saveList) {
                entity.setProvinceCode(areaIdCodeMap.get(entity.getProvinceId()));
                entity.setCityCode(areaIdCodeMap.get(entity.getCityId()));
                entity.setPrefectureCode(areaIdCodeMap.get(entity.getPrefectureId()));
                int i = (int) this.saveCountiesCondition(entity).getData();
                saveNum = saveNum + i;
            }
        }
        if (PlatformObjectUtils.isNotEmpty(updateList)) {
            for (CountiesCondition entity : updateList) {
                int i = (int) this.updateCountiesCondition(entity).getData();
                saveNum = saveNum + i;
            }
        }
        return ResponseCreator.createSuccessResponse(null, "导入成功" + saveNum + "条，一共" + (countiesConditions.size() - count) +
                "条!");
    }

    @Override
    public RestResponse excelImport(MultipartFile file) throws Exception {
        List<CountiesCondition> entityList = new ArrayList<>();
        ExcelResult excelResult = ExcelReaderUtil.readExcelBean(file.getInputStream(), CountiesCondition.class);
        StringBuilder message = new StringBuilder(excelResult.getMessage());
        if (excelResult.getData().size() == 0) {
            return ResponseCreator.createFailResponse(message.toString());
        }
        for (Object datum : excelResult.getData()) {
            CountiesCondition entity = (CountiesCondition) datum;
            String divisionIds = null;
            try {
                //判断省市县的名称是否符合规范
                divisionIds = sysAreaService.getIdByCondition(URLEncoder.encode(entity.getProvince(), "utf-8"),
                        URLEncoder.encode(entity.getCity(), "utf-8"),
                        URLEncoder.encode(entity.getPrefecture(), "utf-8"));
            } catch (Exception e) {
                message.append(entity.getProvince() + "," + entity.getCity() + "," + entity.getPrefecture() + " 省市县的名称不规范.<br/>");
                continue;
            }
            String[] s = divisionIds.split("_");
            if (s.length != 3) {
                message.append(entity.getProvince() + "," + entity.getCity() + "," + entity.getPrefecture() + " 省市县的名称不规范.<br/>");
                continue;
            }
            entityList.add(entity);
        }
        if (entityList.size() == 0) {
            return ResponseCreator.createFailResponse(message.toString());
        }
        if (message.toString().length() > 0) {
            return ResponseCreator.createFailResponse(message.toString());
        }
        for (CountiesCondition condition : entityList) {
            //根据省市区查数据库
            CountiesCondition hosPeo = countiesConditionRepository.getQxCountiesCodition(condition.getProvince(), condition.getCity(), condition.getPrefecture());
            if (hosPeo != null) {
                message.append(hosPeo.getProvince() + "," + hosPeo.getCity() + "," + hosPeo.getPrefecture() + " 该省市区下已有数据,确认是否需要覆盖<br/>");
            }
        }

        if (message.toString().length() > 0) {
            return ResponseCreator.createFailResponse(message.toString());
        }
        for (CountiesCondition entity : entityList) {
            save(entity);
        }
        return ResponseCreator.createSuccessResponse(null, "成功导入" + entityList.size() + "条.");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cover(List<CountiesCondition> conditions) {
        for (CountiesCondition condition : conditions) {
            countiesConditionRepository.delete(condition);
            save(condition);
        }
    }

    @Override
    public Integer countByCounty(String province, String city, String county) {
        return countiesConditionRepository.countByCounty(province, city, county);
    }

    @Override
    public Integer countByCity(String province, String city) {
        return countiesConditionRepository.countByCity(province, city);
    }

    @Override
    public Integer countByProvince(String name) {
        return countiesConditionRepository.countByProvince(name);
    }

    private void save(CountiesCondition entity) {
        String divisionIds = null;
        try {
            divisionIds = sysAreaService.getIdByCondition(URLEncoder.encode(entity.getProvince(), "utf-8"),
                    URLEncoder.encode(entity.getCity(), "utf-8"),
                    URLEncoder.encode(entity.getPrefecture(), "utf-8"));
            String[] split = divisionIds.split("_");
            entity.setProvinceId(split[0]);
            entity.setCityId(split[1]);
            entity.setPrefectureId(split[2]);
        } catch (UnsupportedEncodingException e) {
            log.info(e.getMessage());
        }
        entity.setIsDelete(YNEnum.N.toString());
        entity.setCreateUser(PlatformSessionUtils.getUserId());
        entity.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
        try {
            Map<String, String> areaIdCodeMap = (Map<String, String>) JSONObject.parse(redisTemplate.opsForValue().get(FxfzConstants.CACHE_SYS_KEY + "areaIdCodeMap"));
            entity.setProvinceCode(areaIdCodeMap.get(entity.getProvinceId()));
            entity.setCityCode(areaIdCodeMap.get(entity.getCityId()));
            entity.setPrefectureCode(areaIdCodeMap.get(entity.getPrefectureId()));
        } catch (Exception e) {
            log.info("获取省市区code码错误");
        }
        entity.setCcId(UUIDGenerator.getUUID());
        countiesConditionRepository.saveCountiesCondition(entity);
    }
}
